package main

import (
	"crypto/md5"

	"fileserver/ytcp"
	"fmt"
	"io"
	"time"

	"gitee.com/johng/gf/g"
	"gitee.com/johng/gf/g/encoding/gjson"
	"gitee.com/johng/gf/g/net/ghttp"
	"gitee.com/johng/gf/g/net/gtcp"
	"gitee.com/johng/gf/g/os/gfile"
	"gitee.com/johng/gf/g/util/gconv"
)

type Response struct {
	Success int         `json:"success"`
	Msg     interface{} `json:"msg"`
}

func main() {
	go serveingtcp()
	s := g.Server()
	s.SetPort(9502)

	s.SetWriteTimeout(1200 * time.Second)
	s.BindHandler("/download", func(r *ghttp.Request) {

		fmt.Println("start loading file....")
		params := r.GetRequestMap()

		filepath := "/data/" + params["fs_file_dir"] + params["fs_file_name"]
		if !gfile.Exists(filepath) {
			r.Response.WriteJson(&Response{Success: 2, Msg: "该文件不存在,请核实后重试!"})
			return

		}

		file, err := gfile.Open(filepath)
		if err != nil {
			r.Response.WriteJson(&Response{Success: 2, Msg: err.Error()})
			return
		}
		fileinfo, err := file.Stat()
		if err != nil {
			fmt.Println(err)

		}
		r.Response.Header().Set("Content-Length", gconv.String(fileinfo.Size()))
		reader := make([]byte, 10*1024*1024)
		for {
			n, err := file.Read(reader)
			if err != nil && err != io.EOF {

				fmt.Println(err)

			}
			if n == 0 {
				fmt.Println("传输完成。")
				break
			}

			r.Response.SetBuffer(reader[:n])
			fmt.Println("当前缓冲区大小", len(r.Response.Buffer()))
			r.Response.OutputBuffer()

			time.Sleep(1 * time.Second)
		}

	})
	s.Run()

}

func serveingtcp() {

	//offset := 0
	gtcp.NewServer("0.0.0.0:9503", func(conn *gtcp.Conn) {
		defer conn.Close()

		//fmt.Println("当前偏移量", offset)
		for {
			hdata, filedata, err := ytcp.Recvpkg(conn)
			if err != nil {
				//offset = 0
				if err == io.EOF {
					fmt.Println("传输完成")
					return
				}
				fmt.Println("接收出错", err)
				return
			}

			hdatajson, err := gjson.DecodeToJson(hdata)
			if err != nil {
				fmt.Println("headata解析失败", err)
				return
			}
			if checkverifycode(hdatajson) {
				filedir := "/data/" + hdatajson.GetString("memberuuid") + "/" + time.Now().Format("2006-01-02") + "/"
				if !gfile.Exists(filedir) {
					gfile.Mkdir(filedir)
				}

				filename := hdatajson.GetString("filename")
				if !gfile.Exists(filedir + filename) {
					gfile.Create(filedir + filename)
				}
				file, err := gfile.Open(filedir + filename)
				fileinfo, err := file.Stat()
				if err != nil {
					fmt.Println(err)
					return
				}

				if err != nil {
					fmt.Println("打开文件出错", err)
					return
				}

				if _,err := file.WriteAt(filedata, fileinfo.Size()); err != nil {
					fmt.Println(err)
					return
				}
				if err := file.Sync(); err != nil {
					fmt.Println(err)
					return
				}

				if err := file.Close(); err != nil {
					fmt.Println(err)
					return
				}
			} else {
				fmt.Println("上传码雅正未通过，服务器拒绝接受数据")

			}
		}

	}).Run()
}

//业务需求额外函数，可忽略
func checkverifycode(data *gjson.Json) bool {

	parameter := data.ToMap()
	var pararr [4]string = [4]string{"access_token", "file_md5", "memberuuid", "source_file"}

	str := ""
	for k, val := range pararr {
		fmt.Println("val", k, val)
		fmt.Println("parameter", gconv.String(parameter[val]))
		str += val + "=" + gconv.String(parameter[val]) + "&"
	}
	fmt.Println(str)
	param := str[0 : len(str)-1]
	sign := param + "10isp.com"
	w := md5.New()
	io.WriteString(w, sign)
	verifycode := fmt.Sprintf("%x", w.Sum(nil))

	if verifycode == data.GetString("verifycode") {
		return true
	} else {
		return false
	}

}
